package service

import (
	"devops/controller/validation"
	"devops/models"
	"devops/pkg/tool"
	"errors"
	"fmt"
)

func (d *devOps) GetCiEnvs(cid int) []*models.CiEnv {
	return models.GetCiEnvs(cid)
}

func (d *devOps) GetCiEnv(id int) *models.CiEnv {
	return models.GetCiEnvByID(id)
}

func (d *devOps) CreateCIEnv(param validation.CreateCIEnv) error {
	ci := models.GetCIByID(param.CID)
	if ci == nil {
		return errors.New("构建计划不存在")
	}
	project := models.GetProjectByID(ci.ProjectId)
	if project.ID == 0 {
		return errors.New("项目不存在")
	}

	env := models.GetEnvByCIDName(param.CID, param.Name)
	if env.ID != 0 {
		return errors.New("环境变量已存在")
	}
	err := models.CreateCiEnv(&models.CiEnv{
		CId:            param.CID,
		Name:           param.Name,
		Kind:           param.Kind,
		Default:        param.Default,
		AlternateValue: param.AlternateValue,
		IsSecret:       param.IsSecret,
		Describe:       param.Describe,
	})
	if err != nil {
		return err
	}

	return d.ConfigSubmit(*ci, project.Name)
}

func (d *devOps) GetImageVersion(build models.Build) string {
	imageVersion := models.GetEnvByCIDName(build.CID, "DOCKER_IMAGE_VERSION")
	if imageVersion == nil {
		return ""
	}
	// 自动镜像版本号
	if imageVersion.Default == "${build-BUILD_NUMBER}" {
		return fmt.Sprintf("build-%d", build.Number)
	}
	return imageVersion.Default
}

// 返回启动部署组需要的image参数
func (d *devOps) GetDeployGroupRestartParam(build models.Build) (string, string, string) {
	var repoName, tagName, server string
	tagName = build.ImageTag
	envs := models.GetCiEnvs(build.CID)
	for _, env := range envs {
		if env.Name == "DOCKER_REG_HOST" {
			server = env.Default
		}
		if env.Name == "DOCKER_IMAGE_NAME" {
			repoName = "tsf_1/" + env.Default
		}
	}
	return repoName, tagName, server
}

func (d *devOps) CreateDockerEnv(cid int, repoId int, imageName string, imageVersion string, dockerfilePath string) error {
	repo := models.GetDockerRepoByID(repoId)
	if repo.ID == 0 {
		return errors.New("镜像仓库不存在")
	}
	envs := []models.CiEnv{
		{CId: cid, Name: "WEB_PROTOCOL", Kind: 1, Default: repo.WebProtocol},
		{CId: cid, Name: "DOCKER_REG_HOST", Kind: 1, Default: repo.Host},
		{CId: cid, Name: "DOCKER_PUSH_ADDRESS", Kind: 1, Default: repo.PushAddress},
		{CId: cid, Name: "DOCKER_CREDENTIALS_ID", Kind: 1, Default: repo.CredentialsId},
		{CId: cid, Name: "DOCKER_IMAGE_NAME", Kind: 1, Default: imageName},
		{CId: cid, Name: "DOCKER_IMAGE_VERSION", Kind: 1, Default: imageVersion},
		{CId: cid, Name: "DOCKERFILE_PATH", Kind: 1, Default: dockerfilePath},
	}
	return models.CreateCiEnvs(envs)
}

func (d *devOps) UpdateCiEnv(param validation.UpdateCIEnv) error {
	env := models.GetCiEnvByID(param.EnvID)
	if env.ID == 0 {
		return errors.New("环境变量不存在")
	}
	ci := models.GetCIByID(env.CId)
	if ci == nil {
		return errors.New("构建计划不存在")
	}
	project := models.GetProjectByID(ci.ProjectId)
	if project.ID == 0 {
		return errors.New("项目不存在")
	}

	err := models.UpdateCiEnv(param.EnvID, models.CiEnv{
		Default:        param.Default,
		Describe:       param.Describe,
		AlternateValue: param.AlternateValue,
		IsSecret:       param.IsSecret,
	})
	if err != nil {
		return err
	}
	return d.ConfigSubmit(*ci, project.Name)
}

func (d *devOps) DeleteCIEnv(id int) error {
	env := models.GetCiEnvByID(id)
	if env.ID == 0 {
		return nil
	}
	err := models.DeleteCiEnv(id)
	if err != nil {
		return err
	}
	ci := models.GetCIByID(env.CId)
	if ci == nil {
		return errors.New("构建计划不存在")
	}
	project := models.GetProjectByID(ci.ProjectId)
	if project.ID == 0 {
		return errors.New("项目不存在")
	}

	return d.ConfigSubmit(*ci, project.Name)
}

func (d *devOps) GetEnvStringGit(ci models.CI) string {
	envStr := fmt.Sprintf("GIT_REPO_URL=%s\nGIT_BUILD_REF=%s\n%s", ci.RepositoryUrl, ci.Branch, d.GetEnvString(ci))
	return envStr
}

func (d *devOps) GetEnvString(ci models.CI) string {
	envStr := fmt.Sprintf("CREDENTIALS_ID=%s\n", ci.CredentialsId)
	envs := models.GetCiEnvs(ci.ID)
	for _, env := range envs {
		envStr += fmt.Sprintf("%s=%s\n", env.Name, env.Default)
	}
	return envStr
}

func (d *devOps) GetDiscarder(cid int) models.CiDiscarder {
	return models.GetCiDiscarder(cid)
}

func (d *devOps) GetTiming(cid int) *models.GetCiTimingResp {
	timing := models.GetCiTiming(cid)
	if timing == nil {
		return nil
	}
	return &models.GetCiTimingResp{
		timing.Model, timing.CID, tool.StringToIntSlice(timing.Week, ","), timing.Hour, timing.Minute,
	}
}

func (d *devOps) SetDiscarder(set validation.SetDiscarder) error {
	var err error
	ci := models.GetCIByID(set.CID)
	if ci == nil {
		return errors.New("构建计划不存在")
	}
	project := models.GetProjectByID(ci.ProjectId)
	if project.ID == 0 {
		return errors.New("项目不存在")
	}
	// 设置jenkins
	err = d.ConfigSubmit(*ci, project.Name, Discarder(set.Days, set.Max))
	if err != nil {
		return err
	}
	dis := models.GetCiDiscarder(set.CID)
	data := models.CiDiscarder{Day: set.Days, Max: set.Max}
	if dis.ID == 0 {
		data.CId = set.CID
		err = models.CreateDiscarder(data)
	} else {
		err = models.UpdateCiDiscarder(set.CID, data)
	}

	return err
}

func (d *devOps) SetTiming(set validation.SetTiming) error {
	var err error
	ci := models.GetCIByID(set.CID)
	if ci == nil {
		return errors.New("构建计划不存在")
	}
	project := models.GetProjectByID(ci.ProjectId)
	if project.ID == 0 {
		return errors.New("项目不存在")
	}
	crontab := tool.CrontabExpr(set.Week, set.Hour, set.Minute)
	// 设置jenkins
	err = d.ConfigSubmit(*ci, project.Name, CronExpr(crontab))
	if err != nil {
		return err
	}
	timing := models.GetCiTiming(set.CID)
	data := models.CiTiming{Week: tool.IntSliceToString(set.Week, ","), Hour: set.Hour, Minute: set.Minute}
	if timing == nil {
		err = models.CreateCiTiming(data)
	} else {
		err = models.UpdateCiTiming(set.CID, data)
	}
	return err
}
